﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using FIFP.Common;
using FIFP.DashBoard.Helper;
using FIFP.DashBoard.Model;
using System.Collections.Generic;
using Telerik.Windows.Controls;
using System.Linq;
using System.Collections.ObjectModel;
using System.ComponentModel;
using FIFP.DashBoard.Views;
using FIFP.DashBoard.Converters;

namespace FIFP.DashBoard.ViewModel
{
    public class OverlapVM_New : ViewModelCore
    {
        #region Variables
        public event EventHandler<CustomEventArgs<AppointmentGroup>> OnAppointmentDataCompleted;
        int overlapId = 0;
        private bool isApplySimopsButtonEnabled = false;
        private bool isCancelSimopsButtonEnabled = false;
        #endregion

        #region Properties
        private List<FIFPAppointment> overlapOriginalPlans = new List<FIFPAppointment>();
        public List<FIFPAppointment> OverlapOriginalPlans
        {
            get { return overlapOriginalPlans; }
            set { SetPropertyValue(() => OverlapOriginalPlans, value, val => overlapOriginalPlans = val); }
        }

        private ObservableCollection<OverlapGroup> overlapLocations;
        public ObservableCollection<OverlapGroup> OverlapLocations
        {
            get { return overlapLocations; }
            set { SetPropertyValue(() => OverlapLocations, value, val => overlapLocations = val); }
        }

        private OverlapGroup selectedOverlapLocation;
        public OverlapGroup SelectedOverlapLocation
        {
            get { return selectedOverlapLocation; }
            set { SetPropertyValue(() => SelectedOverlapLocation, value, val => selectedOverlapLocation = val); }
        }

        private Dictionary<int, FIFPAppointment> originalPlansDictionary = new Dictionary<int, FIFPAppointment>();
        public Dictionary<int, FIFPAppointment> OriginalPlansDictionary
        {
            get { return originalPlansDictionary; }
            set { SetPropertyValue(() => OriginalPlansDictionary, value, val => originalPlansDictionary = val); }
        }

        private ObservableCollection<FIFPAppointment> overlappedActivities = new ObservableCollection<FIFPAppointment>();
        public ObservableCollection<FIFPAppointment> OverlappedActivities
        {
            get { return overlappedActivities; }
            set { SetPropertyValue(() => OverlappedActivities, value, val => overlappedActivities = val); }
        }

        private ObservableCollection<FIFPAppointment> selectedUnitOverlappedActivities = new ObservableCollection<FIFPAppointment>();
        public ObservableCollection<FIFPAppointment> SelectedUnitOverlappedActivities
        {
            get { return selectedUnitOverlappedActivities; }
            set { SetPropertyValue(() => SelectedUnitOverlappedActivities, value, val => selectedUnitOverlappedActivities = val); }
        }

        private ObservableCollection<FIFPAppointment> modifiedActivities = new ObservableCollection<FIFPAppointment>();
        public ObservableCollection<FIFPAppointment> ModifiedActivities
        {
            get { return modifiedActivities; }
            set { SetPropertyValue(() => ModifiedActivities, value, val => modifiedActivities = val); }
        }

        private List<FIFPAppointment> selectedAppointments = new List<FIFPAppointment>();
        public List<FIFPAppointment> SelectedAppointments
        {
            get { return selectedAppointments; }
            set { SetPropertyValue(() => SelectedAppointments, value, val => selectedAppointments = val); }
        }
        private List<Unit> unitList = new List<Unit>();
        public List<Unit> UnitList
        {
            get { return unitList; }
            set { SetPropertyValue(() => UnitList, value, val => unitList = val); }
        }

        public bool IsApplySimopsButtonEnabled
        {
            get { return isApplySimopsButtonEnabled; }
            set { SetPropertyValue(() => IsApplySimopsButtonEnabled, value, val => isApplySimopsButtonEnabled = val); }
        }

        public bool IsCancelSimopsButtonEnabled
        {
            get { return isCancelSimopsButtonEnabled; }
            set { SetPropertyValue(() => IsCancelSimopsButtonEnabled, value, val => isCancelSimopsButtonEnabled = val); }
        }
        private int selectedOverlapId;
        public int SelectedOverlapId
        {
            get { return selectedOverlapId; }
            set { SetPropertyValue(() => SelectedOverlapId, value, val => selectedOverlapId = val); }
        }

        private int selectedCancelSIMOPSOverlapId;
        public int SelectedCancelSIMOPSOverlapId
        {
            get { return selectedCancelSIMOPSOverlapId; }
            set { SetPropertyValue(() => SelectedCancelSIMOPSOverlapId, value, val => selectedCancelSIMOPSOverlapId = val); }
        }

        #endregion

        #region Commands
        private ICommand _OverlapLocationSelectionChanged;
        public ICommand OverlapLocationSelectionChanged
        {
            get
            {
                return _OverlapLocationSelectionChanged ??
                        (_OverlapLocationSelectionChanged = new RelayCommand<DataGrid>(OverlapLocationGridSelectionChange));
            }
        }

        private ICommand _OverlapCheckCommand;
        public ICommand OverlapCheckCommand
        {
            get
            {
                return _OverlapCheckCommand ??
                        (_OverlapCheckCommand = new RelayCommand<Button>(CheckOverlapForSelectedLocation));
            }
        }

        private ICommand _ApplySimopsCommand;
        public ICommand ApplySimopsCommand
        {
            get
            {
                return _ApplySimopsCommand ??
                        (_ApplySimopsCommand = new RelayCommand<Button>(ApplySimopsClicked));
            }
        }

        private ICommand _CancelSimopsCommand;
        public ICommand CancelSimopsCommand
        {
            get
            {
                return _CancelSimopsCommand ??
                        (_CancelSimopsCommand = new RelayCommand<Button>(CancelSimopsClicked));
            }
        }

        private ICommand _OverlapActivityCheckedCommand;
        public ICommand OverlapActivityCheckedCommand
        {
            get
            {
                return _OverlapActivityCheckedCommand ??
                        (_OverlapActivityCheckedCommand = new RelayCommand<RadioButton>(IsApplicableForApplySIMOPS));
            }
        }
        private ICommand _OverlapModifiedActivityCheckedCommand;
        public ICommand OverlapModifiedActivityCheckedCommand
        {
            get
            {
                return _OverlapModifiedActivityCheckedCommand ??
                        (_OverlapModifiedActivityCheckedCommand = new RelayCommand<RadioButton>(IsApplicableForCancelSIMOPS));
            }
        }


        #endregion

        #region Constructor
        public OverlapVM_New()
        {
            if (!DesignerProperties.IsInDesignTool)
            {
                ServiceLocator.Get<MainPageVM>().OnOverlapClick += new EventHandler(OverlapVM_OnOverlapClick);
            }
        }
        #endregion

        #region Methods
        void OverlapVM_OnOverlapClick(object sender, EventArgs e)
        {
            overlapId = 0;
            ServiceLocator.Get<AppointmentVM>().RadScheduleViewDragDropBehavior = new OverlapScheduleDragDropBehavior();
            OverlapLocations = new ObservableCollection<OverlapGroup>();
            OverlapOriginalPlans = ServiceLocator.Get<ImportVM>().ImportPlans;
            UnitList = ServiceLocator.Get<ImportVM>().UnitList;
            LoadOriginalPlansIntoDictionary(OverlapOriginalPlans);
            CheckOverlap();
        }

        private void LoadOriginalPlansIntoDictionary(List<FIFPAppointment> planList)
        {
            OriginalPlansDictionary.Clear();
            foreach (FIFPAppointment appointment in planList)
            {
                OriginalPlansDictionary.Add(appointment.PlanID, appointment);
                appointment.IsOverlapped = false;
            }
        }

        private void CheckOverlap()
        {
            List<string> unitTypes = (from item in OverlapOriginalPlans
                                      where item.nIndex > 0
                                      orderby item.nIndex ascending
                                      select item.UnitType).Distinct().ToList<string>();
            foreach (string unitType in unitTypes)
            {

                List<FIFPAppointment> plansWithUnitType = (from item in OverlapOriginalPlans
                                                           where item.UnitType == unitType
                                                           select item).ToList<FIFPAppointment>();
                List<string> unitsWithTheSameUnitTypeList = (from item in plansWithUnitType
                                                             select item.UnitName).Distinct().ToList<string>();

                foreach (string unitName in unitsWithTheSameUnitTypeList)
                {
                    List<FIFPAppointment> plans = (from item in plansWithUnitType
                                                   where item.UnitName == unitName
                                                   select item).ToList<FIFPAppointment>();
                    if (unitType != FIFPConstants.UNITTYPE_TOWER)
                    {
                        if (plans.Count > 1)
                            CheckOverlapForOneUnit(plans, unitName, unitType);
                    }
                    else
                    {
                        if (unitName.LastIndexOf('A') == -1)
                        {                            
                            string alfaTower = unitName + "A";
                            List<string> towerUnitNames = new List<string>();
                            towerUnitNames.Add(unitName);
                            if (unitsWithTheSameUnitTypeList.Contains(alfaTower))
                            {
                                towerUnitNames.Add(alfaTower);
                                plans.AddRange((from item in plansWithUnitType
                                                where item.UnitName == alfaTower
                                                select item).ToList<FIFPAppointment>());
                            }

                            List<string> towerChildUnits = UnitList.Where(s => towerUnitNames.Any(t => t.Equals(s.UnitName))).SelectMany(s => s.ChildUnitList).ToList<Unit>().Select(s => s.UnitName).Distinct().ToList<string>();
                            plans.AddRange(OverlapOriginalPlans.Where(t => towerChildUnits.Any(s => s.Equals(t.UnitName))));
                            towerUnitNames.AddRange(towerChildUnits);
                            bool bRet = CheckOverlapForTowerUnit(plans, unitName, unitType, false);
                            if (bRet)
                            {
                                OverlapGroup overlapGroup = new OverlapGroup(unitName, unitType, towerUnitNames);
                                if (!OverlapLocations.Contains(overlapGroup))
                                    OverlapLocations.Add(overlapGroup);
                            }

                        }
                    }
                }
            }
        }

        //check overlap plans for one unit
        private void CheckOverlapForOneUnit(List<FIFPAppointment> planList, string unitName, string unitType)
        {
            //If it is single unit(Radial, Compressor, Separator, Module, Spheroid, Stripper) we can directly call FlagOverlappedPlans fucntion
            bool bRet = FlagOverlappedPlansForSingleUnit(GetSortList(planList));
            if (bRet)
            {
                OverlapLocations.Add(new OverlapGroup(unitName, unitType));
            }
        }

        private bool CheckOverlapForTowerUnit(List<FIFPAppointment> planList, string unitName, string unitType, bool bUpdate)
        {
            bool isOverlapped = false;
            bool isTowerChecked = false;
            List<string> childUnits = planList.Select(s => s.UnitName).Distinct().ToList<string>();

            List<FIFPAppointment> wellPlans = planList.Where(t => t.UnitType == FIFPConstants.UNITTYPE_WELL).ToList<FIFPAppointment>();
            List<FIFPAppointment> pipelinePlans = planList.Where(t => t.UnitType == FIFPConstants.UNITTYPE_PIPELINE).ToList<FIFPAppointment>();
            List<FIFPAppointment> towerPlans = planList.Where(t => t.UnitType == FIFPConstants.UNITTYPE_TOWER).ToList<FIFPAppointment>();

            bool bRet = false;
            //Overlap checking for Tower and Well               
            List<FIFPAppointment> overlapCheckingPlans = new List<FIFPAppointment>();
            if (wellPlans != null && wellPlans.Count > 0)
            {
                if (towerPlans.Count > 0)
                    isTowerChecked = true;
                overlapCheckingPlans.AddRange(towerPlans);
                overlapCheckingPlans.AddRange(wellPlans);
                bRet = FlagOverlappedPlans(GetSortList(overlapCheckingPlans));
                if (bRet)
                    isOverlapped = bRet;
            }

            //Overlap checking for Tower and Pipeline
            overlapCheckingPlans = new List<FIFPAppointment>();
            if (pipelinePlans != null && pipelinePlans.Count > 0)
            {
                if (towerPlans.Count > 0)
                    isTowerChecked = true;
                overlapCheckingPlans.AddRange(towerPlans);
                overlapCheckingPlans.AddRange(from item in pipelinePlans
                                              where item.ActivityCode != FIFPConstants.ACTIVITY_TYPE_MTN
                                              select item);
                bRet = FlagOverlappedPlans(GetSortList(overlapCheckingPlans));
                if (bRet)
                    isOverlapped = bRet;
            }
            //Overlap checking for Well and Pipeline
            overlapCheckingPlans = new List<FIFPAppointment>();
            if (wellPlans.Count > 0 && pipelinePlans.Count > 0)
            {
                overlapCheckingPlans.AddRange(from item in wellPlans
                                              where item.ActivityCode == FIFPConstants.ACTIVITY_TYPE_RIG
                                              select item);
                overlapCheckingPlans.AddRange(from item in pipelinePlans
                                              where item.ActivityCode != FIFPConstants.ACTIVITY_TYPE_MTN
                                              select item);
                bRet = FlagOverlappedPlans(GetSortList(overlapCheckingPlans));
                if (bRet)
                    isOverlapped = bRet;
            }
            //Overlap checking for Pipeline  
            if (pipelinePlans != null && pipelinePlans.Count > 0)
            {
                bRet = FlagOverlappedPlans(GetSortList(pipelinePlans));
                if (bRet)
                    isOverlapped = bRet;
            }
            //Overlap checking for Tower
            if (!isTowerChecked && towerPlans.Count > 0)
            {
                bRet = FlagOverlappedPlans(GetSortList(towerPlans));
                if (bRet)
                    isOverlapped = bRet;
            }
            if (isOverlapped)
            {
                OverlapGrouping(GetSortList((from item in planList
                                             where childUnits.Any(p => p.Equals(item.UnitName)) && item.IsOverlapped == true
                                             select item).ToList<FIFPAppointment>()));
            }
            return isOverlapped;
        }

        private void OverlapLocationGridSelectionChange(DataGrid locationGrid)
        {
            if (locationGrid != null && locationGrid.SelectedItem != null)
            {
                ModifiedActivities = new ObservableCollection<FIFPAppointment>();
                SelectedOverlapLocation = locationGrid.SelectedItem as OverlapGroup;
                if (SelectedOverlapLocation != null)
                {
                    List<FIFPAppointment> lstModifiedActivities = new List<FIFPAppointment>();
                    if (SelectedOverlapLocation.OverlapType == FIFPConstants.UNITTYPE_TOWER)
                    {
                        SelectedUnitOverlappedActivities = new ObservableCollection<FIFPAppointment>((from item in OverlapOriginalPlans
                                                                                                      where SelectedOverlapLocation.ChildUnits.Any(p => p.Equals(item.UnitName)) && item.IsOverlapped == true
                                                                                                      orderby item.Overlap_Id, item.Start ascending
                                                                                                      select item).ToList<FIFPAppointment>());
                        if (SelectedUnitOverlappedActivities.Count == 0)
                            SelectedUnitOverlappedActivities = new ObservableCollection<FIFPAppointment>((from item in OverlapOriginalPlans
                                                                                                          where SelectedOverlapLocation.ChildUnits.Any(p => p.Equals(item.UnitName)) && item.IsOverlapped == false && item.Overlap_Id > 0
                                                                                                          orderby item.Overlap_Id, item.Start ascending
                                                                                                          select item));
                    }
                    else
                    {
                        SelectedUnitOverlappedActivities = new ObservableCollection<FIFPAppointment>((from item in OverlapOriginalPlans
                                                                                                      where item.UnitName == SelectedOverlapLocation.OverlapLocation && item.IsOverlapped == true
                                                                                                      orderby item.Overlap_Id, item.Start ascending
                                                                                                      select item).ToList<FIFPAppointment>());
                        if (SelectedUnitOverlappedActivities.Count == 0)
                            SelectedUnitOverlappedActivities = new ObservableCollection<FIFPAppointment>((from item in OverlapOriginalPlans
                                                                                                          where item.UnitName == SelectedOverlapLocation.OverlapLocation && item.IsOverlapped == false && item.Overlap_Id > 0
                                                                                                          orderby item.Overlap_Id, item.Start ascending
                                                                                                          select item));
                    }

                    BindGridsAndScheduleView();

                }
            }
        }

        private void BindGridsAndScheduleView()
        {
            if (SelectedOverlapLocation.OverlapType == FIFPConstants.UNITTYPE_TOWER)
            {
                OverlappedActivities = new ObservableCollection<FIFPAppointment>((from item in OverlapOriginalPlans
                                                                                  where SelectedOverlapLocation.ChildUnits.Any(p => p.Equals(item.UnitName)) && item.IsOverlapped == true
                                                                                  orderby item.Overlap_Id, item.Start ascending
                                                                                  select item).ToList<FIFPAppointment>());
                SelectedAppointments = (from item in OverlapOriginalPlans
                                        where SelectedOverlapLocation.ChildUnits.Any(p => p.Equals(item.UnitName))
                                        orderby item.nIndex descending
                                        select item).ToList<FIFPAppointment>();
            }
            else
            {
                OverlappedActivities = new ObservableCollection<FIFPAppointment>((from item in OverlapOriginalPlans
                                                                                  where item.UnitName == SelectedOverlapLocation.OverlapLocation && item.IsOverlapped == true
                                                                                  orderby item.Overlap_Id, item.Start ascending
                                                                                  select item).ToList<FIFPAppointment>());
                SelectedAppointments = (from item in OverlapOriginalPlans
                                        where item.UnitName == SelectedOverlapLocation.OverlapLocation
                                        orderby item.nIndex descending
                                        select item).ToList<FIFPAppointment>();
            }
            List<FIFPAppointment> lstModifiedActivities = new List<FIFPAppointment>(SelectedUnitOverlappedActivities.Except(SelectedUnitOverlappedActivities.Intersect(OverlappedActivities)));
            //lstModifiedActivities.ForEach(p => { p.RadioButtonVisibility = Visibility.Collapsed; p.ModificationReason = FIFPConstants.OVERLAP_REMOVE_TEXT; });
            foreach (FIFPAppointment appointment in lstModifiedActivities)//For apply SIMOPS, we won't change the radio button visibility and modification reason text. Only remove overlap, we can apply modification reason.
            {
                if (!appointment.IsAppliedSimops)
                {
                    appointment.RadioButtonVisibility = Visibility.Collapsed;
                    appointment.ModificationReason = FIFPConstants.OVERLAP_REMOVE_TEXT;
                }
            }
            ModifiedActivities = new ObservableCollection<FIFPAppointment>(lstModifiedActivities);

            LoadOverlapPlans(SelectedAppointments);
        }

        private void CheckOverlapForSelectedLocation(Button btnCheck)
        {
            if (SelectedAppointments != null && SelectedAppointments.Count > 1)
            {
                SelectedAppointments.ForEach(p => { p.IsOverlapped = false; });
                bool bRet = false;
                if (SelectedOverlapLocation.OverlapType == FIFPConstants.UNITTYPE_TOWER)
                {
                    bRet = CheckOverlapForTowerUnit(SelectedAppointments.Where(s => s.IsAppliedSimops == false).ToList<FIFPAppointment>(), SelectedOverlapLocation.OverlapLocation, SelectedOverlapLocation.OverlapType, true);
                }
                else
                    bRet = FlagOverlappedPlansForSingleUnit(GetSortList(SelectedAppointments.Where(s => s.IsAppliedSimops == false).ToList<FIFPAppointment>()));
                if (bRet)
                {
                    //Show message for user that still there are some overlap
                    ShowPopup(FIFPConstants.WARNINGTITLE_OVERLAP, FIFPConstants.WARNINGMESSAGE_OVERLAP);
                }
                else
                {
                    //There is no overlap
                }

                ObservableCollection<FIFPAppointment> CurrentOverlappedActivities = new ObservableCollection<FIFPAppointment>((from item in OverlapOriginalPlans
                                                                                                                               where item.UnitName == SelectedOverlapLocation.OverlapLocation && item.IsOverlapped == true
                                                                                                                               orderby item.Overlap_Id, item.Start ascending
                                                                                                                               select item).ToList<FIFPAppointment>());

                //if(OverlapOriginalPlans != null && OverlapOriginalPlans.Where(o => o.IsOverlapped == true).Count() > 0)
                //    ServiceLocator.Get<MainPageVM>().IsLSDEnabled = false;
                //else
                //    ServiceLocator.Get<MainPageVM>().IsLSDEnabled = true;

                //Rebind Location Grid and Overlapped Activities Grid
                BindGridsAndScheduleView();

            }
        }
        private void ApplySimopsClicked(Button btnApply)
        {
            int maxId = OverlappedActivities.Max(m => m.Overlap_Modification_Id);
            List<FIFPAppointment> simopsActivities = OverlappedActivities.Where(s => s.Overlap_Id == SelectedOverlapId).ToList<FIFPAppointment>();
            int nIndex = 0;
            foreach (FIFPAppointment appointment in simopsActivities)
            {
                appointment.Overlap_Modification_Id = maxId + 1;
                appointment.RadioButtonVisibility = (nIndex == 0) ? Visibility.Visible : Visibility.Collapsed;
                appointment.ModificationReason = FIFPConstants.APPLY_SIMOPS_TEXT;
                appointment.IsAppliedSimops = true;
                appointment.IsOverlapped = false;
                nIndex++;
            }
            OverlappedActivities = new ObservableCollection<FIFPAppointment>(OverlappedActivities.Where(s => s.Overlap_Id != SelectedOverlapId));
            ModifiedActivities.AddRange(simopsActivities);
            IsApplySimopsButtonEnabled = false;
            if (SelectedOverlapLocation.OverlapType == FIFPConstants.UNITTYPE_TOWER)
            {
                LoadOverlapPlans((from item in OverlapOriginalPlans
                                  where SelectedOverlapLocation.ChildUnits.Any(p => p.Equals(item.UnitName))
                                  orderby item.nIndex descending
                                  select item).ToList<FIFPAppointment>());
            }
            else
                LoadOverlapPlans((from item in OverlapOriginalPlans
                                  where item.UnitName == SelectedOverlapLocation.OverlapLocation
                                  orderby item.nIndex descending
                                  select item).ToList<FIFPAppointment>());
            //ServiceLocator.Get<AppointmentVM>().Appointments.Where(w => w.Overlap_Id == SelectedOverlapId).ToList<FIFPAppointment>().ForEach(c => { c.Category = new Category("", new SolidColorBrush(Colors.Gray)); });
            //ServiceLocator.Get<AppointmentVM>().Appointments.Where(w => w.Overlap_Id == SelectedOverlapId).ToList<FIFPAppointment>().ForEach(c => { c.Category = new Category("", new SolidColorBrush(new Color() { R = 0x80, G = 0x80, B = 0x80, A = 0xFF })); });

        }
        private void CancelSimopsClicked(Button btnCancel)
        {
            List<FIFPAppointment> simopsActivities = ModifiedActivities.Where(m => m.Overlap_Id == SelectedCancelSIMOPSOverlapId).ToList<FIFPAppointment>();
            simopsActivities.ForEach(c => { c.IsAppliedSimops = false; c.IsOverlapped = true; c.ModificationReason = string.Empty; });
            OverlappedActivities.AddRange(simopsActivities);
            ModifiedActivities = new ObservableCollection<FIFPAppointment>(ModifiedActivities.Where(m => m.Overlap_Id != SelectedCancelSIMOPSOverlapId));
            IsCancelSimopsButtonEnabled = false;
            if (SelectedOverlapLocation.OverlapType == FIFPConstants.UNITTYPE_TOWER)
            {
                LoadOverlapPlans((from item in OverlapOriginalPlans
                                  where SelectedOverlapLocation.ChildUnits.Any(p => p.Equals(item.UnitName))
                                  orderby item.nIndex descending
                                  select item).ToList<FIFPAppointment>());
            }
            else
                LoadOverlapPlans((from item in OverlapOriginalPlans
                                  where item.UnitName == SelectedOverlapLocation.OverlapLocation
                                  orderby item.nIndex descending
                                  select item).ToList<FIFPAppointment>());
        }
        private void IsApplicableForCancelSIMOPS(RadioButton rdBtn)
        {
            if (rdBtn != null && rdBtn.Tag != null)
            {
                SelectedCancelSIMOPSOverlapId = Convert.ToInt32(rdBtn.Tag);
                IsCancelSimopsButtonEnabled = true;
            }
        }
        private void IsApplicableForApplySIMOPS(RadioButton rdBtn)
        {
            if (rdBtn != null && rdBtn.Tag != null)
            {
                SelectedOverlapId = Convert.ToInt32(rdBtn.Tag);
                if (SelectedOverlapLocation.OverlapType == FIFPConstants.UNITTYPE_TOWER && SelectedOverlapId > 0)
                {
                    if (OverlappedActivities.Where(s => s.Overlap_Id == SelectedOverlapId).Count() == 2)
                        IsApplySimopsButtonEnabled = true;
                    else
                    {
                        IsApplySimopsButtonEnabled = false;
                        ShowPopup(FIFPConstants.WARNINGTITLE_APPLYSIMOPS, FIFPConstants.WARNINGMESSAGE_APPLYSIMOPS);
                    }
                }
            }
        }
        private void ShowPopup(string title, string message)
        {
            Warning warningWindow = new Warning();
            warningWindow.CancelButton.Visibility = Visibility.Collapsed;
            warningWindow.Title = title;
            warningWindow.lblMessage.Text = message;
            warningWindow.lblMessage.Visibility = Visibility.Visible;
            warningWindow.Show();
        }

        private void LoadOverlapPlans(List<FIFPAppointment> plans)
        {
            //set red for overlapped plans, green for non-overlapped plans
            foreach (FIFPAppointment appointment in plans)
            {
                appointment.Category = (appointment.IsAppliedSimops) ? new Category("", new SolidColorBrush(Colors.Gray)) : (appointment.IsOverlapped) ? new Category("", new SolidColorBrush(Colors.Red)) : new Category("", new SolidColorBrush(Colors.Green));
            }

            AppointmentGroup appointmentGroup = new AppointmentGroup();
            List<ResourceType> lstResources = new List<ResourceType>();
            List<Resource> unitList = new List<Resource>();
            ResourceType unitType = new ResourceType("Unit");
            unitType.DisplayName = "Unit";
            unitType.Name = "Unit";

            foreach (FIFPAppointment appointment in plans)
            {
                Resource resource = new Resource() { ResourceName = appointment.UnitName, DisplayName = appointment.UnitName, ResourceType = unitType.Name };
                //unitList.Add(resource);
                if (!unitList.Contains(resource))
                {
                    unitList.Add(resource);
                }
                appointment.Resources.Add(resource);
            }

            appointmentGroup.Appointments = new List<FIFPAppointment>(plans);
            unitType.Resources.AddRange(unitList);
            lstResources.Add(unitType);


            appointmentGroup.ResourceTypes = lstResources;
            appointmentGroup.UnitList = unitList;

            if (OnAppointmentDataCompleted != null)
                OnAppointmentDataCompleted(this, new CustomEventArgs<AppointmentGroup>(appointmentGroup));

        }

        #region Overlap Checking algrithom
        //input  : activities for one unit
        //output : a list filled with PlanForSort,  and it is sorted with all start date and end date
        private List<PlanForSort> GetSortList(List<FIFPAppointment> list)
        {
            List<PlanForSort> sortedList = new List<PlanForSort>();
            //create the list for sort
            foreach (FIFPAppointment a in list)
            {
                //flag = 1  means it is a  start date
                //flag = -1 means it is an end date
                sortedList.Add(new PlanForSort(a.PlanID, a.Start, 1));
                sortedList.Add(new PlanForSort(a.PlanID, a.End, -1));
            }
            //sort
            sortedList.Sort();
            return sortedList;
        }

        //input  : sorted list of activitiesforplan for one unit        
        private bool FlagOverlappedPlansForSingleUnit(List<PlanForSort> list)
        {
            bool returnFlag = false;
            int sumFlag = 0;
            List<FIFPAppointment> tempList = new List<FIFPAppointment>();

            foreach (PlanForSort plan in list)
            {
                //sumflag == 0 means it is a new overlap group, so 
                //create a new list for activities in this overlap group
                //add the current activity
                //add the list to the result 
                if (sumFlag == 0)
                {
                    List<FIFPAppointment> lstAppointment = new List<FIFPAppointment>();
                    lstAppointment.Add(OriginalPlansDictionary[plan.id]);

                    sumFlag += plan.flag;

                    if (tempList.Count > 1)//This is no needed. Later we have to modify.
                    {
                        overlapId++;
                        int nIndex = 0;
                        foreach (FIFPAppointment appointment in tempList)
                        {
                            if (!appointment.IsOverlapped)
                            {
                                appointment.IsOverlapped = true;
                                appointment.Overlap_Id = overlapId;
                                appointment.RadioButtonVisibility = (nIndex == 0) ? Visibility.Visible : Visibility.Collapsed;
                                nIndex++;
                            }
                        }
                        returnFlag = true;
                    }
                    tempList = lstAppointment;
                }
                //sumflag != 0 means it is in the process of the overlap group
                else
                {
                    if (plan.flag == 1)
                    {
                        tempList.Add(OriginalPlansDictionary[plan.id]);
                    }

                    sumFlag += plan.flag;

                    if (sumFlag == 0)
                    {
                        if (tempList.Count > 1)
                        {
                            overlapId++;
                            int nIndex = 0;
                            foreach (FIFPAppointment appointment in tempList)
                            {
                                if (!appointment.IsOverlapped)
                                {
                                    appointment.IsOverlapped = true;
                                    appointment.Overlap_Id = overlapId;
                                    appointment.RadioButtonVisibility = (nIndex == 0) ? Visibility.Visible : Visibility.Collapsed;
                                    nIndex++;
                                }
                            }
                            tempList = new List<FIFPAppointment>();
                            returnFlag = true;
                        }
                    }
                }
            }
            return returnFlag;
        }

        #region Overlap Checking algrithom


        //input  : sorted list of activitiesforplan for one unit        
        private bool FlagOverlappedPlans(List<PlanForSort> list)
        {
            bool returnFlag = false;
            int sumFlag = 0;
            List<FIFPAppointment> tempList = new List<FIFPAppointment>();

            foreach (PlanForSort a in list)
            {
                //sumflag == 0 means it is a new overlap group, so 
                //create a new list for activities in this overlap group
                //add the current activity
                //add the list to the result 
                if (sumFlag == 0)
                {
                    List<FIFPAppointment> l = new List<FIFPAppointment>();
                    l.Add(OriginalPlansDictionary[a.id]);

                    sumFlag += a.flag;

                    if (tempList.Count > 1)
                    {
                        foreach (FIFPAppointment p in tempList)
                        {
                            p.IsOverlapped = true;
                        }
                        returnFlag = true;
                    }
                    tempList = l;
                }
                //sumflag != 0 means it is in the process of the overlap group
                else
                {
                    if (a.flag == 1)
                    {
                        tempList.Add(OriginalPlansDictionary[a.id]);
                    }

                    sumFlag += a.flag;

                    if (sumFlag == 0)
                    {
                        if (tempList.Count > 1)
                        {
                            foreach (FIFPAppointment p in tempList)
                            {
                                p.IsOverlapped = true;
                            }
                            tempList = new List<FIFPAppointment>();
                            returnFlag = true;
                        }
                    }
                }
            }
            return returnFlag;
        }


        #endregion

        private void OverlapGrouping(List<PlanForSort> list)
        {
            int sumFlag = 0;
            List<FIFPAppointment> tempList = new List<FIFPAppointment>();

            foreach (PlanForSort plan in list)
            {
                //sumflag == 0 means it is a new overlap group, so 
                //create a new list for activities in this overlap group
                //add the current activity
                //add the list to the result 
                if (sumFlag == 0)
                {
                    List<FIFPAppointment> lstAppointment = new List<FIFPAppointment>();
                    lstAppointment.Add(OriginalPlansDictionary[plan.id]);

                    sumFlag += plan.flag;

                    if (tempList.Count > 1)//This is no needed. Later we have to modify.
                    {
                        overlapId++;
                        int nIndex = 0;
                        foreach (FIFPAppointment appointment in tempList)
                        {
                            appointment.Overlap_Id = overlapId;
                            appointment.RadioButtonVisibility = (nIndex == 0) ? Visibility.Visible : Visibility.Collapsed;
                            nIndex++;
                        }
                    }
                    tempList = lstAppointment;
                }
                //sumflag != 0 means it is in the process of the overlap group
                else
                {
                    if (plan.flag == 1)
                    {
                        tempList.Add(OriginalPlansDictionary[plan.id]);
                    }

                    sumFlag += plan.flag;

                    if (sumFlag == 0)
                    {
                        if (tempList.Count > 1)
                        {
                            overlapId++;
                            int nIndex = 0;
                            foreach (FIFPAppointment appointment in tempList)
                            {
                                appointment.Overlap_Id = overlapId;
                                appointment.RadioButtonVisibility = (nIndex == 0) ? Visibility.Visible : Visibility.Collapsed;
                                nIndex++;
                            }
                            tempList = new List<FIFPAppointment>();
                        }
                    }
                }
            }
        }

        #endregion
        #endregion
    }
}
